#include "player.h"

Player::Player(QTcpSocket* socket)
{
    mName = "";
    mRoom = defaultRoom;
    mBlack = true;
    mSocket = socket;

    connect(mSocket, &QTcpSocket::readyRead, this, &Player::slotTcpMsg); //收到消息时发出readyRead,触发槽函数
}

void Player::slotTcpMsg()
{
    int nHeaderLen = sizeof(MSG_HEADER);                //取消息头长度
    if (mSocket->bytesAvailable() <= 0) {                //检查套接字接收缓冲区中当前可用的字节数
        return;
    }
    QByteArray data = mSocket->readAll();               //获取接收数据
    mData += data;                                      //data加入缓存区

    while(1) {
        if (mData.size() < nHeaderLen) {
            //当前接收内容不足一个消息头长度，无法处理继续接收
            return;
        }
        MSG_HEADER* pMsg = (MSG_HEADER*)mData.data();   //创建个消息头，为刚接收的数据（消息头+附加数据）
        if (mData.size() < nHeaderLen + pMsg->nDataLen) {
            //当前接收内容足一个消息头，但不足解析本消息需要的总长度(头长度+头里指定的数据长度)
            return;
        }

        //判断是不是服务器认识的消息
        if (pMsg->nType == MQ_LOGON ||
            pMsg->nType == MQ_MOVE ||
            pMsg->nType == MQ_MOVECC ||
            pMsg->nType == MQ_SUCCESS ||
            pMsg->nType == MQ_SAY ||
            pMsg->nType == MQ_HEARTBEAT) {

            emit sigRecvMsg((char*)(pMsg), pMsg->nDataLen);  //接收消息信号
        }
        else {
            //不认识的消息
            mData.clear();
            return;
        }
        mData.remove(0, nHeaderLen + pMsg->nDataLen);        //缓存区清空
    }
}

bool Player::Send(MSG_HEADER msg)
{
    mSocket->write((char*)&msg, sizeof(MSG_HEADER));
    mSocket->flush();                                //确保所有缓冲的数据都被发送
    return true;
}

bool Player::Send(MSG_HEADER msg, char *pData, int nDataLen)
{
    int nLen = sizeof(MSG_HEADER) + nDataLen;
    char* buf = new char[nLen];
    memset(buf, 0, nLen);
    memcpy(buf, (char*)&msg, sizeof(MSG_HEADER));
    memcpy(buf + sizeof(MSG_HEADER), pData, nDataLen);

    mSocket->write(buf, nLen);
    mSocket->flush();

    delete []buf;
    return true;
}

void Player::UpdateHeartbeat()
{
    mHeartBeatTime = QDateTime::currentDateTime();
}

bool Player::IsHeartbeatTimeout()
{
    if (mHeartBeatTime.msecsTo(QDateTime::currentDateTime()) >= 5000) {
        return true;
    }
    return false;
}

QString Player::getPlayermName()
{
    return this->mName;
}

int Player::getPlayermRoom()
{
    return this->mRoom;
}

bool Player::getPlayermBlack()
{
    return this->mBlack;
}

QString Player::setPlayermName(QString name)
{
    this->mName = name;
}

int Player::setPlayermRoom(int room)
{
    this->mRoom = room;
}

bool Player::setPlayermBlack(bool black)
{
    this->mBlack = black;
}


